bitkeeper revision 1.193 (3eae9e8fDbEyBEL7yKPAlkULZMIM4g)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 29 Apr 2003 15:47:27 +0000 (15:47 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 29 Apr 2003 15:47:27 +0000 (15:47 +0000)
network.c, dev.c, vif.h, hypervisor-if.h, kernel.c, domain.c:
  Allow DHCP from domain-0 Xenolinux. Link-local IP addresses are now allocated consecutively from 169.254.1.0.

xen/common/domain.c
xen/common/kernel.c
xen/common/network.c
xen/include/hypervisor-ifs/hypervisor-if.h
xen/include/xeno/vif.h
xen/net/dev.c
xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c

index 349acc5b578e98d2c845ce5f030c0816f63a705c..0542743341d365b5aabf5e22a212b952a00625a2 100644 (file)
@@ -377,6 +377,8 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo)
         if ( p->net_vif_list[i] == NULL ) continue;
         virt_startinfo_addr->net_rings[i] = 
             virt_to_phys(p->net_vif_list[i]->shared_rings);
+        memcpy(virt_startinfo_addr->net_vmac[i],
+               p->net_vif_list[i]->vmac, ETH_ALEN);
     }
 
     /* Add block io interface */
@@ -645,6 +647,8 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
         if ( p->net_vif_list[i] == NULL ) continue;
         virt_startinfo_address->net_rings[i] = 
             virt_to_phys(p->net_vif_list[i]->shared_rings);
+        memcpy(virt_startinfo_address->net_vmac[i],
+               p->net_vif_list[i]->vmac, ETH_ALEN);
     }
 
     /* Add block io interface */
index 67602c113934caf6e7f04148bf4b9e3c2dff01ea..6e92cfefc78018536ca88c63d142873af6df29a8 100644 (file)
@@ -424,7 +424,6 @@ unsigned short compute_cksum(unsigned short *buf, int count)
 /* XXX SMH: below is rather vile; pulled in to allow network console */
 
 extern int netif_rx(struct sk_buff *); 
-extern struct net_device *the_dev;
 
 typedef struct my_udphdr {
     __u16 source;
@@ -499,8 +498,8 @@ int console_export(char *str, int len)
     iph->id      = 0xdead;
     iph->ttl     = 255;
     iph->protocol= 17;
-    iph->daddr   = htonl(0xa9fe0001);  /* 169.254.0.1 */
-    iph->saddr   = htonl(0xa9fe0001);  /* 169.254.0.1 */
+    iph->daddr   = htonl(0xa9fe0100);  /* 169.254.1.0 */
+    iph->saddr   = htonl(0xa9fe0100);  /* 169.254.1.0 */
     iph->tot_len = htons(hdr_size + len); 
     iph->check  = 0;
     iph->check   = compute_cksum((__u16 *)iph, sizeof(struct my_iphdr)/2); 
index 80d27e7bd6aca254689c7e4c4c14c4030166b474..f7c5f3b7c270a66693c2d13982a89709c1fefb1f 100644 (file)
@@ -104,6 +104,14 @@ net_vif_t *create_net_vif(int domain)
     spin_lock_init(&new_vif->rx_lock);
     spin_lock_init(&new_vif->tx_lock);
 
+    /*
+     * Virtual MAC is a hash of the real physical MAC. Chosen so that the 
+     * first vif of domain 0 gets the physical MAC address.
+     */
+    memcpy(new_vif->vmac, the_dev->dev_addr, ETH_ALEN);
+    ((unsigned short *)new_vif->vmac)[1] ^= htons(p->domain);
+    ((unsigned short *)new_vif->vmac)[2] ^= htons(dom_vif_idx);
+
     p->net_vif_list[dom_vif_idx] = new_vif;
     
     write_unlock_irqrestore(&tasklist_lock, flags);
@@ -496,8 +504,6 @@ long do_network_op(network_op_t *u_network_op)
 
 void __init net_init (void)
 {
-    net_rule_t new_rule;
-
     net_rule_list = NULL;
     net_vif_cache = kmem_cache_create("net_vif_cache", 
                                       sizeof(net_vif_t),
@@ -505,20 +511,4 @@ void __init net_init (void)
     net_rule_cache = kmem_cache_create("net_rule_cache", 
                                        sizeof(net_rule_ent_t),
                                        0, SLAB_HWCACHE_ALIGN, NULL, NULL);
-
-    /* Bootstrap outbound rule. */
-    memset(&new_rule, 0, sizeof(net_rule_t));
-    new_rule.src_vif = 0;
-    new_rule.dst_vif = VIF_PHYSICAL_INTERFACE;
-    new_rule.action = NETWORK_ACTION_ACCEPT;
-    new_rule.proto = NETWORK_PROTO_ANY;
-    add_net_rule(&new_rule);
-
-    /* Bootstrap inbound rule. */
-    memset(&new_rule, 0, sizeof(net_rule_t));
-    new_rule.src_vif = VIF_ANY_INTERFACE;
-    new_rule.dst_vif = 0;
-    new_rule.action = NETWORK_ACTION_ACCEPT;
-    new_rule.proto = NETWORK_PROTO_ANY;
-    add_net_rule(&new_rule);
 }
index 6b74f92b6675b151d2d6ae2a0654e0ad98c23a03..6a4c6b817ca72470410a214a0f0071d2bf654ceb 100644 (file)
@@ -241,6 +241,7 @@ typedef struct start_info_st {
     unsigned long mod_len;       /* size (bytes) of pre-loaded module */
     /* Machine address of net rings for each VIF. Will be page aligned. */
     unsigned long net_rings[MAX_DOMAIN_VIFS];
+    unsigned char net_vmac[MAX_DOMAIN_VIFS][6];
     /* Machine address of block-device ring. Will be page aligned. */
     unsigned long blk_ring;
     unsigned int  dom_id;
index 4fb2e275d1460d27ab9362ec23d8145a431bed51..6cc339cbd9b8690e0c5ef4cb60648eb0ba3e5b18 100644 (file)
 
 #include <hypervisor-ifs/network.h>
 
+#include <xeno/if_ether.h>
+
+extern struct net_device *the_dev;
+
 /* 
  * shadow ring structures are used to protect the descriptors from
  * tampering after they have been passed to the hypervisor.
@@ -69,6 +73,7 @@ typedef struct net_vif_st {
     struct list_head    list;     /* scheduling list */
     atomic_t            refcnt;
     spinlock_t          rx_lock, tx_lock;
+    unsigned char       vmac[ETH_ALEN];
 } net_vif_t;
 
 #define get_vif(_v) (atomic_inc(&(_v)->refcnt))
index 87144aa1622ea6748cd5421ef6567bbfa8182fc6..0f36344e74979eb7959f36e50a1e693bf70276ee 100644 (file)
@@ -500,9 +500,9 @@ void deliver_packet(struct sk_buff *skb, net_vif_t *vif)
     unsigned short size;
     unsigned char  offset, status = RING_STATUS_OK;
 
-    memset(skb->mac.ethernet->h_dest, 0, ETH_ALEN);
+    memcpy(skb->mac.ethernet->h_dest, vif->vmac, ETH_ALEN);
     if ( ntohs(skb->mac.ethernet->h_proto) == ETH_P_ARP )
-        memset(skb->nh.raw + 18, 0, ETH_ALEN);
+        memcpy(skb->nh.raw + 18, vif->vmac, ETH_ALEN);
 
     if ( (i = vif->rx_cons) == vif->rx_prod )
         return;
@@ -741,7 +741,7 @@ static void net_tx_action(unsigned long unused)
             add_to_net_schedule_list_tail(vif);
 
         skb->destructor = tx_skb_release;
-        
+
         skb->head = skb->data = tx->header;
         skb->end  = skb->tail = skb->head + PKT_PROT_LEN;
         
@@ -1728,7 +1728,7 @@ inline int init_tx_header(u8 *data, unsigned int len, struct net_device *dev)
     {
     case ETH_P_ARP:
         if ( len < 42 ) break;
-        memcpy(data + 22, dev->dev_addr, 6);
+        memcpy(data + 22, dev->dev_addr, ETH_ALEN);
         return ETH_P_ARP;
     case ETH_P_IP:
         return ETH_P_IP;
@@ -1939,7 +1939,7 @@ long do_net_update(void)
                   (PGT_writeable_page | current->domain)) || 
                  (buf_page->tot_count != 1) )
             {
-               DPRINTK("Need a mapped-once writeable page (%d/%d/%08x)\n",
+               DPRINTK("Need a mapped-once writeable page (%ld/%ld/%08lx)\n",
                buf_page->type_count, buf_page->tot_count, buf_page->flags);
                 make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
                 goto rx_unmap_and_continue;
index 7cf0fecbec68259f9fb8e9afdd3b0406f1fd9fd2..a125695e54245cca248140a431d7a7921d287057 100644 (file)
@@ -470,9 +470,9 @@ static int inetdev_notify(struct notifier_block *this,
     (void)HYPERVISOR_network_op(&op);
 
     /*
-     * Xen creates a pair of bootstrap rules which allows domain 0 to
-     * send and receive any packet. These rules can be removed once we
-     * have configured an IP address.
+     * When the first real interface is brought up we delete the start-of-day
+     * bootstrap rules -- they were only installed to allow an initial DHCP
+     * request and response.
      */
     if ( (idx == 0) && (event == NETDEV_UP) && !removed_bootstrap_rules )
     {
@@ -480,11 +480,9 @@ static int inetdev_notify(struct notifier_block *this,
         op.cmd = NETWORK_OP_DELETERULE;
         op.u.net_rule.proto         = NETWORK_PROTO_ANY;
         op.u.net_rule.action        = NETWORK_ACTION_ACCEPT;
-
         op.u.net_rule.src_vif       = 0;
         op.u.net_rule.dst_vif       = VIF_PHYSICAL_INTERFACE;
         (void)HYPERVISOR_network_op(&op);
-
         op.u.net_rule.src_vif       = VIF_ANY_INTERFACE;
         op.u.net_rule.dst_vif       = 0;
         (void)HYPERVISOR_network_op(&op);
@@ -511,13 +509,32 @@ int __init init_module(void)
 
     INIT_LIST_HEAD(&dev_list);
 
-    /*
-     * Domain 0 must poke its own network rules as it discovers its IP
-     * addresses. All other domains have a privileged "parent" to do this
-     * for them at start of day.
-     */
     if ( start_info.dom_id == 0 )
+    {
+        /*
+         * Domain 0 creates wildcard rules to allow DHCP to find its first IP
+         * address. These wildcard rules are deleted when the first inet
+         * interface is brought up.
+         */
+        network_op_t op;
+        memset(&op, 0, sizeof(op));
+        op.cmd = NETWORK_OP_ADDRULE;
+        op.u.net_rule.proto         = NETWORK_PROTO_ANY;
+        op.u.net_rule.action        = NETWORK_ACTION_ACCEPT;
+        op.u.net_rule.src_vif       = 0;
+        op.u.net_rule.dst_vif       = VIF_PHYSICAL_INTERFACE;
+        (void)HYPERVISOR_network_op(&op);
+        op.u.net_rule.src_vif       = VIF_ANY_INTERFACE;
+        op.u.net_rule.dst_vif       = 0;
+        (void)HYPERVISOR_network_op(&op);        
+
+        /*
+         * Domain 0 must poke its own network rules as it discovers its IP
+         * addresses. All other domains have a privileged "parent" to do this
+         * for them at start of day.
+         */
         (void)register_inetaddr_notifier(&notifier_inetdev);
+    }
 
     for ( i = 0; i < MAX_DOMAIN_VIFS; i++ )
     {
@@ -548,8 +565,7 @@ int __init init_module(void)
         dev->stop            = network_close;
         dev->get_stats       = network_get_stats;
 
-        memset(dev->dev_addr, 0, ETH_ALEN);
-        *(unsigned int *)(dev->dev_addr + 1) = i;
+        memcpy(dev->dev_addr, start_info.net_vmac[i], ETH_ALEN);
 
         if ( (err = register_netdev(dev)) != 0 )
         {